package com.demospringboot.utils;

import java.security.MessageDigest;
import java.util.Locale;
import java.util.UUID;

/**
 * 密码处理类
 */
public class PasswordUtils {
    //md5加密
    private static String md5(String s){
        try {
            // MessageDigest是封装md5算法的工具对象还支持SHA算法
            MessageDigest md =MessageDigest.getInstance("MD5");
            // 通过digest拿到的任意字符串,得到的bytes都是等长的
            byte[] bytes = md.digest(s.getBytes("utf-8"));
            // 返回十六进制字符串
            return toHex(bytes);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    // 把二进制转换成十六进制
    public static String toHex(byte[] bytes){
        // 声明一个十六进制字符数组
        final char[] HEX_DIGEST = "0123456789ABCDEF".toCharArray();
        StringBuilder sb = new StringBuilder(bytes.length * 2);
        // 循环是为了补位操作
        for (int i = 0; i < bytes.length; i++) {
             /*
             ? >> 4意思是:例如31对应二进制的11001,右移4位00001,前面补0,得到1
             而0x0f对应二进制的00001111,16进制数为15,
             而31右移之后结果为00000001,&之后结果是1,所以HEX_DIGITS[1]得到1
             */
            sb.append(HEX_DIGEST[(bytes[i] >> 4) & 0x0f]);
            sb.append(HEX_DIGEST[bytes[i] & 0x0f]);
        }
        return sb.toString();
    }
    // 生成随机字符串,长度8位的UUID
    public static String salt(){
        //使用UUID通用唯一识别码,取第一个-前面的值
        UUID uuid = UUID.randomUUID();
        String[] arr = uuid.toString().split("-");
        // 返回第一个
        return arr[0].toUpperCase(Locale.ROOT);
    }
    // 对密码进行加密加盐操作
    public static String md5AndSalt(String pwd){
        // 对密码进行加密
        String md5Pwd = md5(pwd);
        // 生成盐
        String salt = salt();
        StringBuilder sb = new StringBuilder(md5Pwd);
        // 将盐插入第18位的位置
        sb.insert(18,salt);
        return sb.toString();
    }
    // 校验密码是否正确
    public static Boolean match(String password,String dbPassword){
        StringBuilder sb = new StringBuilder(dbPassword);
        if(dbPassword.length()<26){
            return false;
        }
        // 去盐操作,去掉18-26位生成的uuid
        sb.replace(18,26,"");
        // 对新密码进行加密,生成MD5加密字符
        password = md5(password);
        // 匹配两个密码是否相等
        return password.equals(sb.toString());
    }

    public static void main(String[] args) {
        String pwd = "123456";//E10ADC3949BA59ABBE56E057F20F883E
                              //E10ADC3949BA59ABBEe696919856E057F20F883E
                              //E10ADC3949BA59ABBE173b144156E057F20F883E
        //String md5Pwd = md5(pwd);
        //String salt = md5AndSalt(pwd);
        //match(pwd,salt)
        //System.out.println(salt);
        System.out.println(PasswordUtils.md5AndSalt("111"));
    }
}
